package com.topscomm.core.factory.ftp;

import java.io.InputStream;
import java.util.Map;

import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;

import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SecurityUtil;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.topscomm.core.AbstractFileStoreService;
import com.topscomm.core.FileStoreTypeEnum;
import com.topscomm.core.IFileStoreService;
import com.topscomm.file.FileInfoDTO;
import com.topscomm.file.FtpConfig;
import com.topscomm.file.util.Utils;

/**
 * ftp文件服务
 *
 * @description:
 * @author: donghang
 * @date: 2021年3月13日下午10:52:00
 * @modify:
 */
public class FtpFileStoreService extends AbstractFileStoreService implements IFileStoreService {
	private static final Logger LOG = LoggerFactory.getLogger(FtpFileStoreService.class);
	private String host, username, password, workDir;
	private int port = 21;
	private KeyManager keyManager;
	private TrustManager trustManager;
	private boolean isWorkDirNotEmpty = false, isSSL = false;
	private int default_timeout = 3000;

	public FtpFileStoreService(String host, int port, String username, String password, String workDir,
			String keyManagerPath, String keyManagerPassword, String trustManagerPath, String trustManagerPassword) {
		super(FileStoreTypeEnum.FTP.protocol);
		this.host = host;
		this.username = username;
		this.password = password;
		this.workDir = workDir;
		this.isWorkDirNotEmpty = Utils.isNotEmpty(workDir) ? "/".equals(workDir) : false;
		try {
			if (Utils.isNotEmpty(keyManagerPath)) {
				keyManager = Utils.getKeyManager(keyManagerPath, keyManagerPassword);
				trustManager = Utils.getTrustManager(trustManagerPath, trustManagerPassword);
				isSSL = true;
			}
		} catch (Exception e) {
			throw new RuntimeException("load keyManager,trustManager failed,异常:{}", e);
		}

		this.port = port;
	}

	public FtpFileStoreService(FtpConfig ftpConfig) {
		this(SecurityUtil.decryptDes(ftpConfig.getHost(), ftpConfig.getDecryptKey()),
				ftpConfig.getPort(),
				SecurityUtil.decryptDes(ftpConfig.getUsername(), ftpConfig.getDecryptKey()),
				SecurityUtil.decryptDes(ftpConfig.getPassword(), ftpConfig.getDecryptKey()),
				SecurityUtil.decryptDes(ftpConfig.getWorkDir(), ftpConfig.getDecryptKey()), null, null, null, null);
	}

	/**
	 * 得到ftp客户端连接
	 *
	 * @description:
	 * @return
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月15日上午9:09:17
	 * @modify:
	 */
	public FTPClient getFtpClient() throws Exception {
		try {
			FTPClient ftpClient = null;
			if (isSSL) {
				FTPSClient ftpsClient = new FTPSClient(true);
				ftpsClient.setKeyManager(keyManager);
				ftpsClient.setTrustManager(trustManager);
				// ftpsClient.execPBSZ(0);
				// ftpsClient.execPROT("P");
				ftpClient = ftpsClient;
			} else {
				ftpClient = new FTPClient();
			}
			ftpClient.setDefaultTimeout(default_timeout);
			ftpClient.connect(host, port);
			ftpClient.login(username, password);
			int reply = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				LOG.info("{} ftp server 拒绝连接", host);
			}
			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
			if (isWorkDirNotEmpty) {
				ftpClient.changeWorkingDirectory(workDir);
			}
			ftpClient.setControlEncoding("UTF-8");
			return ftpClient;

		} catch (Exception e) {
			LOG.error("{} ftp server connect failed,异常", e);
			throw e;
		}
	}

	/**
	 *
	 * @description:
	 * @param fileInfo
	 * @return
	 * @author: donghang
	 * @date: 2021年3月18日下午2:28:38
	 * @modify:
	 */
	@Override
	public Map<String, Object> initMultiPartUpload(FileInfoDTO fileInfo) {
		return null;
	}

	/**
	 *
	 * @description:
	 * @param fileInfo
	 * @param uploadId
	 * @return
	 * @author: donghang
	 * @date: 2021年3月18日下午2:28:41
	 * @modify:
	 */
	@Override
	public boolean mergeMultipartUpload(FileInfoDTO fileInfo, String uploadId) {
		return false;
	}

	/**
	 * 预签名的
	 *
	 * @description:
	 * @param inputStream
	 * @param url
	 * @return
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月18日下午3:30:31
	 * @modify:
	 */

	@Override
	public String uploadPresigned(InputStream inputStream, String url) throws Exception {
		return null;
	}

	/**
	 * 路径上传
	 *
	 * @description:
	 * @param filePath
	 * @return
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月16日下午1:48:47
	 * @modify:
	 */
	@Override
	public String upload(FileInfoDTO fileInfo) throws Exception {
		return null;
	}

	/**
	 * ftp上传
	 *
	 * @description:
	 * @param system
	 * @param inputStream
	 * @param fileName
	 * @return
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月15日上午9:09:34
	 * @modify:
	 */
	@Override
	public String upload(InputStream inputStream, FileInfoDTO fileInfo) throws Exception {
		FTPClient ftpClient = getFtpClient();
		try {
			FTPClient client = getFtpClient();
			String filePath = fileInfo.getRemoteFilePath();
			mkdirs(filePath);
			client.storeFile(filePath, inputStream);
			return filePath;
		} finally {
			close(ftpClient);
		}
	}

	/**
	 * 删除
	 *
	 * @description:
	 * @param fileId
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月15日上午9:10:09
	 * @modify:
	 */
	@Override
	public void delete(FileInfoDTO fileInfo) throws Exception {
		FTPClient ftpClient = getFtpClient();
		try {
			ftpClient.deleteFile(fileInfo.getRemoteFilePath());
		} finally {
			close(ftpClient);
		}

	}

	/**
	 * 下载
	 *
	 * @description:
	 * @param fileId
	 * @param outputStream
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月15日上午9:09:57
	 * @modify:
	 */
	@Override
	public InputStream downLoad(FileInfoDTO fileInfo) throws Exception {
		return null;
	}

	/**
	 * 下载文件到本地
	 *
	 * @description:
	 * @param fileInfo
	 * @param filePath
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月18日下午11:28:00
	 * @modify:
	 */
	@Override
	public void downLoad(FileInfoDTO fileInfo, String filePath) throws Exception {

	}

	/**
	 *
	 * @description:
	 * @param fileInfo
	 * @return
	 * @author: donghang
	 * @date: 2021年4月1日下午11:57:53
	 * @modify:
	 */
	@Override
	public String accessUrl(FileInfoDTO fileInfo) {
		return null;
	}

	/**
	 * 创建目录
	 *
	 * @description:
	 * @param path
	 * @throws Exception
	 * @author: donghang
	 * @date: 2021年3月15日上午9:10:29
	 * @modify:
	 */
	public void mkdirs(String path) throws Exception {
		try {
			FTPClient client = getFtpClient();
			int index = path.lastIndexOf("/");
			if (index > 0) {
				client.makeDirectory(path.substring(0, index));
			} else if (path.endsWith("/")) {
				client.makeDirectory(path);
			}
		} catch (Exception e) {
			LOG.error("mkdirs {}  failed,异常", path, e);
			throw e;
		}
	}

	/**
	 * 关闭ftp
	 *
	 * @description:
	 * @param ftpClient
	 * @author: donghang
	 * @date: 2021年3月15日上午9:10:41
	 * @modify:
	 */
	public void close(FTPClient ftpClient) {
		try {
			if (ftpClient != null) {
				ftpClient.disconnect();
			}
		} catch (Exception e) {
			LOG.error("close error", e);
		}
	}

	@Override
	public String getUpdateId(FileInfoDTO fileInfo) {
		return null;
	}

	@Override
	public boolean fileIsExist(FileInfoDTO fileInfo) {
		return false;
	}

}
